package com.snpic.appaw.module.insure.service.carmessage;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.snpic.appaw.framework.common.constants.SystemConstant;
import com.snpic.appaw.framework.common.exception.ServiceException;
import com.snpic.appaw.module.insure.controller.app.vehicleInformation.vo.AppVehicleInformationSaveReqVO;
import com.snpic.appaw.module.insure.dal.dataobject.customer.CustomerDO;
import com.snpic.appaw.module.insure.dal.dataobject.cxImage.CxImageDO;
import com.snpic.appaw.module.insure.dal.dataobject.cxParty.CxPartyDO;
import com.snpic.appaw.module.insure.dal.dataobject.cxProvince.CxProvinceDO;
import com.snpic.appaw.module.insure.dal.mysql.customer.CustomerMapper;
import com.snpic.appaw.module.insure.dal.mysql.cxImage.CxImageMapper;
import com.snpic.appaw.module.insure.enums.common.BooleanEnum;
import com.snpic.appaw.module.insure.service.cxProvince.CxProvinceService;
import com.snpic.appaw.module.insure.service.orc.ClientOCRService;
import com.snpic.appaw.module.insure.service.vehicleInformation.VehicleInformationService;
import com.snpic.appaw.module.third.api.bjpt.dto.CarModel;
import com.snpic.appaw.module.third.api.bjpt.dto.CarModelInfoInquiryReqDto;
import com.snpic.appaw.module.third.api.bjpt.dto.CarModelInfoInquiryReqTotalDto;
import com.snpic.appaw.module.third.api.bjpt.dto.CarModelInfoInquiryRespTotalDto;
import com.snpic.appaw.module.third.api.bjpt.dto.iSPolicyQuery.ISMotorDTO;
import com.snpic.appaw.module.third.api.bjpt.dto.iSPolicyQuery.ISPolicyQueryDetailResDTO;
import com.snpic.appaw.module.third.api.bjpt.dto.iSPolicyQuery.ISRelatedPartyDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import com.snpic.appaw.module.insure.controller.app.carmessage.vo.*;
import com.snpic.appaw.module.insure.dal.dataobject.carmessage.CarMessageDO;
import com.snpic.appaw.framework.common.pojo.PageResult;
import com.snpic.appaw.framework.common.pojo.PageParam;
import com.snpic.appaw.framework.common.util.object.BeanUtils;

import com.snpic.appaw.module.insure.dal.mysql.carmessage.CarMessageMapper;

import static com.snpic.appaw.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.snpic.appaw.framework.common.util.collection.CollectionUtils.convertList;
import static com.snpic.appaw.framework.common.util.collection.CollectionUtils.diffList;
import static com.snpic.appaw.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static com.snpic.appaw.module.insure.enums.ErrorCodeConstants.*;

/**
 * 车险出单-车辆信息 Service 实现类
 *
 * @author lqs
 */
@Service
@Slf4j
public class CarMessageServiceImpl implements CarMessageService {

	@Resource
	private CarMessageMapper carMessageMapper;

	@Resource
	private VehicleInformationService vehicleInformationService;

	@Resource
	private CustomerMapper customerMapper;

	@Resource
	private CxProvinceService cxProvinceService;

	@Resource
	private ClientOCRService clientOCRService;

	@Resource
	private CxImageMapper cxImageMapper;

	@Override
	@Transactional
	public AppCarMessageSaveRespVO createCarMessage(AppCarMessageSaveReqVO createReqVO) {
		Long customerId = getLoginUserId();
		Boolean ownerStatus = createReqVO.getOwnerStatus();
		//1.
		//2.实名判断
		CustomerDO customerDO = customerMapper.selectById(customerId);
		if (customerDO == null || !SystemConstant.StrOne.equals(customerDO.getIdAuth()) || StrUtil.isEmpty(customerDO.getIdType()) || StrUtil.isEmpty(customerDO.getIdNo())) {
			log.error("当前登录用户未实名,customerDO = {}", customerDO);
			throw exception(LOGIN_USER_NOT_VERIFIED);
		}
		//2.1 把车主信息填入
		if (StrUtil.isEmpty(createReqVO.getIdNo())) {
			createReqVO.setIdType(customerDO.getIdType());
			createReqVO.setIdNo(customerDO.getIdNo());
			createReqVO.setOwnerName(customerDO.getRealName());
		}
		//3. 判断车牌和投保城市是否一致
		//3.1 调用车牌查询投保城市方法
		String cityCode = createReqVO.getCitycode();
		String licensePlateNumber = createReqVO.getLicenseNo();
		//3.2 调用,根据车牌号码查询车险出单配置-市与车险省市映射
		CxProvinceDO cxProvinceDO = cxProvinceService.getCxProvinceByPlateNo(licensePlateNumber);
		String cxCityCode = cxProvinceDO.getCxCityCode();
		//3.3 比较投保城市和车牌城市是否一致
		if (!cityCode.equals(cxCityCode)) {
			log.error("投保城市{}和车牌{}不一致", cxProvinceDO.getCxCityName(), licensePlateNumber);
			throw exception(INSURANCE_QUOTE_UNABLE);
		}
		//4.是否是过户车
		if (createReqVO.getTransferFlag()) {
			log.error("过户车,不能投保");
			throw exception(INSURANCE_QUOTE_UNABLE);
		}
		//5.是否是七座以上车
		//5.1 调用,车辆车型查询接口
		String rackNo = createReqVO.getRackNo();
		if (StrUtil.isNotEmpty(rackNo)) {
			CarModelInfoInquiryReqTotalDto carModelInfoInquiryReqTotalDto = new CarModelInfoInquiryReqTotalDto();
			CarModelInfoInquiryReqDto requestBody = carModelInfoInquiryReqTotalDto.getRequestBody();
			requestBody.setVin(rackNo);
			requestBody.setInquiryType(SystemConstant.StrOne);
			CarModelInfoInquiryRespTotalDto carModelInfoInquiryRespTotalDto = vehicleInformationService.carModelInfoInquiry(licensePlateNumber, carModelInfoInquiryReqTotalDto);
			if (carModelInfoInquiryRespTotalDto == null) {
				log.error("根据vin查询\"报价平台-车辆车型\"结果为空");
				throw exception(CAR_MODEL_INFO_INQUIRY_RESP_IS_NULL);
			}
			//5.2 carModelInfoInquiryRespTotalDto一些可用信息赋值到 createReqVO
			CarModel carModel_carModelInfoInquiry = carModelInfoInquiryRespTotalDto.getResponseBody().getCarModelList().get(0);
			//座位号
			createReqVO.setSeats(carModelInfoInquiryRespTotalDto.getResponseBody().getSeatCount());
			//号牌种类
			createReqVO.setLicensetype(carModelInfoInquiryRespTotalDto.getResponseBody().getLicenseTypeCode());
			//品牌型号
			createReqVO.setVehicleBrand(carModel_carModelInfoInquiry.getModelcname());
			//能源类型
			createReqVO.setFuelType(carModelInfoInquiryRespTotalDto.getResponseBody().getFuelType());
		}
		//5.3 比较车车型是否是七座以上
		if (createReqVO.getSeats() != null && createReqVO.getSeats() >= 7) {
			log.error("七座以上车,不能投保");
			throw exception(INSURANCE_QUOTE_UNABLE);
		}
		//6. 判断进入报价期


		//7.从历史保单获取信息(车辆信息,被保险人信息)
		CarMessageDO carMessage = BeanUtils.toBean(createReqVO, CarMessageDO.class);
		//7.1根据车牌号前缀plateNo_prefix去查询得到机构号和操作员工号(虚拟员工)
		//cxProvinceDO已经存在
		//7.2 开始调用，报价平台，历史保单查询,rackNo(vin)可能null
		ISPolicyQueryDetailResDTO isPolicyQueryDetailResDTO = clientOCRService.invokeQueryHisPolicyDetail(cxProvinceDO.getIssueCompany(), cxProvinceDO.getSalesmanCode(), licensePlateNumber, rackNo);
		//保险人被保险人DO,用于返回值构建
		CxPartyDO cxPartyDO = null;
		if (isPolicyQueryDetailResDTO != null) {
			ISMotorDTO motorDTO = isPolicyQueryDetailResDTO.getMotorList().get(0);
			//7.3 进行逻辑判断,覆写carMessage的某些属性(车辆信息)
			//车架号
			if (StrUtil.isEmpty(carMessage.getRackNo())) {
				carMessage.setRackNo(motorDTO.getFrameNo());
			}
			if (StrUtil.isEmpty(carMessage.getEngineNo())) {
				//发动机号
				carMessage.setEngineNo(motorDTO.getEngineNo());
			}
			if (ObjectUtil.isNull(carMessage.getRegisterDate())) {
				carMessage.setRegisterDate(motorDTO.getSingeinDate());
			}
			//7.4 TODO 被保险人信息插入数据表
			cxPartyDO = new CxPartyDO();
			ISRelatedPartyDTO insuredPersionInfo = null;
			for (ISRelatedPartyDTO isRelatedPartyDTO : isPolicyQueryDetailResDTO.getRelatedPartyList()) {
				//寻找被保险人insuredPersionInfo
				if (SystemConstant.StrTwo.equals(isRelatedPartyDTO.getInsuredFlag())) {
					insuredPersionInfo = isRelatedPartyDTO;
				}
			}
			if (insuredPersionInfo != null) {
				cxPartyDO.setInsuredname(insuredPersionInfo.getInsuredName());
				cxPartyDO.setInsuredgender(insuredPersionInfo.getSex());
				cxPartyDO.setInsuredidtype(insuredPersionInfo.getIdentifyType());
				cxPartyDO.setInsuredidno(insuredPersionInfo.getIdentifyNumber());
				cxPartyDO.setInsuredbirthdate(insuredPersionInfo.getBirthDate());
				cxPartyDO.setInsuredmobile(insuredPersionInfo.getMobilePhone());
				cxPartyDO.setInsuredstartdate(insuredPersionInfo.getCertiStartDate());
				cxPartyDO.setInsuredenddate(insuredPersionInfo.getCertiEndDate());

			}

		}


		//8.绑车页面没有车辆,就需要在那里添加一台车,根据createReqVO.getVehicleInformationCreateFlag()判断是否需要添加
		Long vehicleInformationId = null;
		if (Boolean.TRUE.equals(createReqVO.getVehicleInformationCreateFlag())) {
			// 1.2 调用"首页车辆卡片/编辑家庭档案 - 创建车辆信息"
			AppVehicleInformationSaveReqVO vehicleInformationSaveReqVO = new AppVehicleInformationSaveReqVO()
				.setLicensePlateNumber(createReqVO.getLicenseNo())
				.setOwnerStatus(ownerStatus)
				.setTransfered(createReqVO.getTransferFlag());
			vehicleInformationId = vehicleInformationService.createVehicleInformation(vehicleInformationSaveReqVO);
		}

		//9.1 插入行驶证影像
		long cxImageId = cxImageMapper.insert(CxImageDO.builder()
			.carPlate(createReqVO.getLicenseNo())
			.carOwnerName(createReqVO.getOwnerName())
			.carOwnerIdno(createReqVO.getIdNo())
			.rackNo(createReqVO.getRackNo())
			.engineNo(createReqVO.getEngineNo())
			.registerDate(createReqVO.getRegisterDate())
			.vehicleLicenseHeadUrl(createReqVO.getVehicleLisenceUrl())
			.build()
		);
		// 9.2插入cx_message
		carMessage.setTransferFlag(BooleanEnum.fromBoolean(createReqVO.getTransferFlag()).getValue());
		carMessage.setCustomerId(customerId);
		carMessage.setCxIamgeId(cxImageId);
		carMessageMapper.insert(carMessage);

		//10返回
		AppCarMessageSaveRespVO appCarMessageSaveRespVO = new AppCarMessageSaveRespVO();
		appCarMessageSaveRespVO.setCarMessage(carMessage);
		appCarMessageSaveRespVO.setCxParty(cxPartyDO);
		return appCarMessageSaveRespVO;
	}

	@Override
	public void updateCarMessage(AppCarMessageSaveReqVO updateReqVO) {
		// 校验存在
		validateCarMessageExists(updateReqVO.getId());
		// 更新
		CarMessageDO updateObj = BeanUtils.toBean(updateReqVO, CarMessageDO.class);
		carMessageMapper.updateById(updateObj);
	}

	@Override
	public void deleteCarMessage(Long id) {
		// 校验存在
		validateCarMessageExists(id);
		// 删除
		carMessageMapper.deleteById(id);
	}

	@Override
	public void deleteCarMessageListByIds(List<Long> ids) {
		// 删除
		carMessageMapper.deleteByIds(ids);
	}


	private void validateCarMessageExists(Long id) {
		if (carMessageMapper.selectById(id) == null) {
			throw exception(CAR_MESSAGE_NOT_EXISTS);
		}
	}

	@Override
	public CarMessageDO getCarMessage(Long id) {
		return carMessageMapper.selectById(id);
	}

	@Override
	public PageResult<CarMessageDO> getCarMessagePage(AppCarMessagePageReqVO pageReqVO) {
		return carMessageMapper.selectPage(pageReqVO);
	}

	/**
	 * 获得车险出单-车辆信息列表
	 * 只能差当前登录用户
	 *
	 * @param pageReqVO
	 * @return
	 */
	@Override
	public List<CarMessageDO> getCarMessageList(AppCarMessagePageReqVO pageReqVO) {
		pageReqVO.setCustomerId(getLoginUserId());
		List<CarMessageDO> carMessageDoList = carMessageMapper.selectList(pageReqVO);
		return carMessageDoList;
	}

}